package com.zzz.email.service;

import com.zzz.email.config.EmailConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @BelongsProject: oj-project
 * @BelongsPackage: com.zzz.email.service
 * @Author: zzz
 * @CreateTime: 2025-10-25  22:30
 * @Description: 邮件模板服务
 * @Version: 1.0
 */
@Slf4j
@Service
public class EmailTemplateService {
    
    @Autowired
    private EmailConfig emailConfig;
    
    @Autowired
    private ResourceLoader resourceLoader;
    
    @Autowired
    @Qualifier("emailTemplateEngine")
    private TemplateEngine templateEngine;
    
    /**
     * 渲染邮件模板
     *
     * @param templateType 模板类型 (html/text)
     * @param templatePath 模板路径
     * @param params 参数
     * @return 渲染后的内容
     */
    public String renderTemplate(String templateType, String templatePath, Map<String, Object> params) {
        try {
            // 根据模板类型进行渲染
            if ("html".equalsIgnoreCase(templateType)) {
                return renderHtmlTemplate(templatePath, params);
            } else {
                // 对于文本模板，使用简单字符串替换
                String templateContent = loadTemplateContent(templatePath);
                return renderTextTemplate(templateContent, params);
            }
        } catch (Exception e) {
            log.error("邮件模板渲染失败，使用默认模板", e);
            // 降级处理：使用默认模板
            return String.format(emailConfig.getVerificationCodeTemplate(), 
                params.get("code"), params.get("expireMinutes"));
        }
    }
    
    /**
     * 加载模板文件内容
     *
     * @param templatePath 模板路径
     * @return 模板内容
     */
    private String loadTemplateContent(String templatePath) throws IOException {
        Resource resource = resourceLoader.getResource(templatePath);
        try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) {
            return FileCopyUtils.copyToString(reader);
        }
    }
    
    /**
     * 渲染HTML模板（使用Thymeleaf）
     *
     * @param templatePath 模板路径
     * @param params 参数
     * @return 渲染后的内容
     */
    private String renderHtmlTemplate(String templatePath, Map<String, Object> params) {
        try {
            // 从模板路径中提取模板名称（去掉前缀和后缀）
            String templateName = templatePath;
            if (templateName.startsWith("classpath:templates/")) {
                templateName = templateName.substring("classpath:templates/".length());
            }
            if (templateName.endsWith(".html")) {
                templateName = templateName.substring(0, templateName.length() - ".html".length());
            }
            
            // 创建Thymeleaf上下文
            Context context = new Context();
            context.setVariables(params);
            
            // 使用Thymeleaf模板引擎渲染
            return templateEngine.process(templateName, context);
        } catch (Exception e) {
            log.error("HTML模板渲染失败，降级使用字符串替换", e);
            // 降级处理：使用字符串替换
            try {
                String templateContent = loadTemplateContent(templatePath);
                return renderTextTemplate(templateContent, params);
            } catch (IOException ex) {
                log.error("降级处理也失败", ex);
                return String.format(emailConfig.getVerificationCodeTemplate(), 
                    params.get("code"), params.get("expireMinutes"));
            }
        }
    }
    
    /**
     * 渲染文本模板
     *
     * @param templateContent 模板内容
     * @param params 参数
     * @return 渲染后的内容
     */
    private String renderTextTemplate(String templateContent, Map<String, Object> params) {
        String result = templateContent;
        
        // 替换变量占位符
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String placeholder = "${" + entry.getKey() + "}";
            if (result.contains(placeholder)) {
                result = result.replace(placeholder, String.valueOf(entry.getValue()));
            }
        }
        
        return result;
    }
}